산술 연산자¶
산술 연산자¶
산술 연산자는 덧셈, 뺄셈, 곱셈, 나눗셈을 위한 이항(binary) 연산자와 양수, 음수를 나타내기 위한 단항(unary) 연산자가 있다. 양수/음수의 부호를 나타내는 단항 연산자의 연산 우선순위가 이항 연산자보다 높다.
<expression> <mathematical_operator> <expression>
<expression> ::=
bit_string |
character_string |
numeric_value |
date-time_value |
collection_value |
NULL
<mathematical_operator> ::=
<set_arithmetic_operator> |
<arithmetic_operator>
<arithmetic_operator> ::=
+ |
- |
* |
{ / | DIV } |
{ % | MOD }
<set_arithmetic_operator> ::=
UNION |
DIFFERENCE |
{ INTERSECT | INTERSECTION }
- <expression>: 연산을 수행할 수식을 선언한다.
- <mathematical_operator>: 수학적 연산을 지정하는 연산자로서, 산술 연산자와 집합 연산자가 있다.
- <set_arithmetic_operator>: 컬렉션 타입의 피연산자에 대해 합집합, 차집합, 교집합을 수행하는 집합 산술 연산자이다.
- <arithmetic_operator>: 사칙 연산을 수행하기 위한 연산자이다.
다음은 CUBRID가 지원하는 산술 연산자의 설명 및 리턴 값을 나타낸 표이다.
산술 연산자
산술 연산자 | 설명 | 연산식 | 리턴 값 |
---|---|---|---|
+ | 더하기 연산 | 1+2 | 3 |
- | 빼기 연산 | 1-2 | -1 |
* | 곱하기 연산 | 1*2 | 2 |
/ | 나누기 연산 후, 몫을 반환한다. | 1/2.0 | 0.500000000 |
DIV | 나누기 연산 후, 몫을 반환한다. 피연산자는 정수 타입이어야 하며, 정수를 반환한다. | 1 DIV 2 | 0 |
% , MOD | 나누기 연산 후, 나머지를 반환한다. 피연산자는 정수 타입이어야 하며, 정수를 반환한다. 피연산자가 실수이면 MOD 함수를 이용한다. | 1 % 2 1 MOD 2 | 1 |
수치형 데이터 타입의 산술 연산과 타입 변환¶
모든 수치형 데이터 타입을 산술 연산에 사용할 수 있으며, 연산 결과 타입은 피연산자의 데이터 타입과 연산의 종류에 따라 다르다. 아래는 피연산자 타입별 덧셈/뺄셈/곱셈 연산의 결과 데이터 타입을 정리한 표이다.
피연산자의 타입별 결과 데이터 타입
INT | NUMERIC | FLOAT | DOUBLE | |
---|---|---|---|---|
INT | INT 또는 BIGINT | NUMERIC | FLOAT | DOUBLE |
NUMERIC | NUMERIC | NUMERIC (p와 s도 변환됨) | DOUBLE | DOUBLE |
FLOAT | FLOAT | DOUBLE | FLOAT | DOUBLE |
DOUBLE | DOUBLE | DOUBLE | DOUBLE | DOUBLE |
피연산자가 모두 동일한 데이터 타입이면 연산 결과의 타입이 변환되지 않으나, 나누기 연산의 경우 예외적으로 타입이 변환되므로 주의해야 한다. 분모, 즉 제수(divisor)가 0이면 에러가 발생한다.
아래는 피연산자가 모두 NUMERIC 타입인 경우, 연산 결과의 전체 자릿수(p)와 소수점 아래 자릿수(s)를 정리한 표이다.
NUMERIC 타입의 연산 결과
연산 | 결과의 최대 자릿수 | 결과의 소수점 이하 자릿수 |
---|---|---|
N(p1, s1) + N(p2, s2) | max(p1-s1, p2-s2)+max(s1, s2) +1 | max(s1, s2) |
N(p1, s1) - N(p2, s2) | max(p1-s1, p2-s2)+max(s1, s2) | max(s1, s2) |
N(p1, s1) * N(p2, s2) | p1+p2+1 | s1+s2 |
N(p1, s1) / N(p2, s2) | s2 > 0 이면 Pt = p1+max(s1, s2) + s2 - s1, 그 외에는 Pt = p1라 하고, s1 > s2 이면 St = s1, 그 외에는 s2라 하면, 소수점 이하 자릿수는 St < 9 이면 min(9-St, 38-Pt) + St, 그 외에는 St |
예제
--int * int
SELECT 123*123;
123*123
=============
15129
-- int * int returns overflow error
SELECT (1234567890123*1234567890123);
ERROR: Data overflow on data type bigint.
-- int * numeric returns numeric type
SELECT (1234567890123*CAST(1234567890123 AS NUMERIC(15,2)));
(1234567890123* cast(1234567890123 as numeric(15,2)))
======================
1524157875322755800955129.00
-- int * float returns float type
SELECT (1234567890123*CAST(1234567890123 AS FLOAT));
(1234567890123* cast(1234567890123 as float))
===============================================
1.524158e+024
-- int * double returns double type
SELECT (1234567890123*CAST(1234567890123 AS DOUBLE));
(1234567890123* cast(1234567890123 as double))
================================================
1.524157875322756e+024
-- numeric * numeric returns numeric type
SELECT (CAST(1234567890123 AS NUMERIC(15,2))*CAST(1234567890123 AS NUMERIC(15,2)));
( cast(1234567890123 as numeric(15,2))* cast(1234567890123 as numeric(15,2)))
======================
1524157875322755800955129.0000
-- numeric * float returns double type
SELECT (CAST(1234567890123 AS NUMERIC(15,2))*CAST(1234567890123 AS FLOAT));
( cast(1234567890123 as numeric(15,2))* cast(1234567890123 as float))
=======================================================================
1.524157954716582e+024
-- numeric * double returns double type
SELECT (CAST(1234567890123 AS NUMERIC(15,2))*CAST(1234567890123 AS DOUBLE));
( cast(1234567890123 as numeric(15,2))* cast(1234567890123 as double))
========================================================================
1.524157875322756e+024
-- float * float returns float type
SELECT (CAST(1234567890123 AS FLOAT)*CAST(1234567890123 AS FLOAT));
( cast(1234567890123 as float)* cast(1234567890123 as float))
===============================================================
1.524158e+024
-- float * double returns float type
SELECT (CAST(1234567890123 AS FLOAT)*CAST(1234567890123 AS DOUBLE));
( cast(1234567890123 as float)* cast(1234567890123 as double))
================================================================
1.524157954716582e+024
-- double * double returns float type
SELECT (CAST(1234567890123 AS DOUBLE)*CAST(1234567890123 AS DOUBLE));
( cast(1234567890123 as double)* cast(1234567890123 as double))
=================================================================
1.524157875322756e+024
-- int / int returns int type without type conversion or rounding
SELECT 100100/100000;
100100/100000
===============
1
-- int / int returns int type without type conversion or rounding
SELECT 100100/200200;
100100/200200
===============
0
-- int / zero returns error
SELECT 100100/(100100-100100);
ERROR: Attempt to divide by zero.
날짜/시간 데이터 타입의 산술 연산과 타입 변환¶
피연산자가 모두 날짜/시간 데이터 타입이면 뺄셈 연산이 가능하며, 리턴 값의 타입은 BIGINT 이다. 이때 피연산자의 타입에 따라 연산 단위가 다르므로 주의한다. 날짜/시간 데이터 타입과 정수는 덧셈 및 뺄셈 연산이 가능하며, 이때 연산 단위와 리턴 값의 타입은 날짜/시간 데이터 타입을 따른다.
아래는 피연산자의 타입별로 허용하는 연산과 연산 결과의 데이터 타입을 정리한 표이다.
피연산자의 타입별 허용 연산과 결과 데이터 타입
TIME (초 단위) | DATE (일 단위) | TIMESTAMP (초 단위) | DATETIME (밀리초 단위) | INT | |
---|---|---|---|---|---|
TIME | 뺄셈만 허용. BIGINT | X | X | X | 덧셈, 뺄셈 허용. TIME |
DATE | X | 뺄셈만 허용. BIGINT | 뺄셈만 허용. BIGINT | 뺄셈만 허용. BIGINT | 덧셈, 뺄셈 허용. DATE |
TIMESTAMP | X | 뺄셈만 허용. BIGINT | 뺄셈만 허용. BIGINT | 뺄셈만 허용. BIGINT | 덧셈, 뺄셈 허용. TIMESTAMP |
DATETIME | X | 뺄셈만 허용. BIGINT | 뺄셈만 허용. BIGINT | 뺄셈만 허용. BIGINT | 덧셈, 뺄셈 허용. DATETIME |
INT | 덧셈, 뺄셈 허용 TIME | 덧셈, 뺄셈 허용. DATE | 덧셈, 뺄셈 허용. TIMESTAMP | 덧셈, 뺄셈 허용. DATETIME | 모든 산술 연산 허용 |
Note
날짜/시간 산술 연산의 인자 중 하나라도 NULL 이 포함되어 있으면 수식의 결과로 NULL 이 반환된다.
예제
-- initial systimestamp value
SELECT SYSDATETIME;
SYSDATETIME
===============================
07:09:52.115 PM 01/14/2010
-- time type + 10(seconds) returns time type
SELECT (CAST (SYSDATETIME AS TIME) + 10);
( cast( SYS_DATETIME as time)+10)
====================================
07:10:02 PM
-- date type + 10 (days) returns date type
SELECT (CAST (SYSDATETIME AS DATE) + 10);
( cast( SYS_DATETIME as date)+10)
====================================
01/24/2010
-- timestamp type + 10(seconds) returns timestamp type
SELECT (CAST (SYSDATETIME AS TIMESTAMP) + 10);
( cast( SYS_DATETIME as timestamp)+10)
=========================================
07:10:02 PM 01/14/2010
-- systimestamp type + 10(milliseconds) returns systimestamp type
SELECT (SYSDATETIME + 10);
( SYS_DATETIME +10)
===============================
07:09:52.125 PM 01/14/2010
SELECT DATETIME '09/01/2009 03:30:30.001 pm'- TIMESTAMP '08/31/2009 03:30:30 pm';
datetime '09/01/2009 03:30:30.001 pm'-timestamp '08/31/2009 03:30:30 pm'
=======================================
86400001
SELECT TIMESTAMP '09/01/2009 03:30:30 pm'- TIMESTAMP '08/31/2009 03:30:30 pm';
timestamp '09/01/2009 03:30:30 pm'-timestamp '08/31/2009 03:30:30 pm'
=======================================
86400